package com.example.springmvcproject.Service;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.example.springmvcproject.Mapper.CreditMapper;
import com.example.springmvcproject.Mapper.UserMapper;
import com.example.springmvcproject.Pojo.User;
import com.example.springmvcproject.Service.Inteface.UserService;
import com.example.springmvcproject.Utils.ResultCode;
import com.example.springmvcproject.Utils.ResultMessage;
import com.example.springmvcproject.Utils.SaTokenUtils;
import com.example.springmvcproject.Vo.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.Result;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;

@Service
@Transactional
@Log4j2
public class UserServiceImpl implements UserService {
    @Resource
    UserMapper userMapper;
    @Resource
    CreditMapper creditMapper;
    /**
     * @param userVo 前端传递账号密码
     * @return
     */
    @Override
    public ResultMessage insertUser(UserVo userVo) {
        int userCount=userMapper.selectCountByAccount(userVo.getAccount());
        if (userCount>0) {
            return new ResultMessage(1,200,null,"该账号已经被注册过了");
        }
        //生成UUID加盐
        String key= UUID.randomUUID().toString().replace("-","");
        String password= SaTokenUtils.getAesEncrypt(key,userVo.getPassword());
        User user = new User(null, userVo.getAccount(), password, key,new Date().getTime(), 2);
        userMapper.insertUser(user);
        return new ResultMessage(0,200,null,"注册成功");
    }

    /**
     * 通过用户名密码登录并返回token
     * @param userVo
     * @return
     */
    @Override
    public ResultMessage getLoginByAccountAndPassword(UserVo userVo) {
        //根据账号查询具体用户
        User user = userMapper.selectUserByAccount(userVo.getAccount());
        if (user==null) {
            return new ResultMessage(ResultCode.RESULT_NULL.getCode(), ResultCode.RESULT_NULL.getStatus(), "您登陆的账号不存在",null);
        }
        //或许账号对应的加盐key并解密
        String password=SaTokenUtils.getAesDecrypt(user.getUserKey(),user.getUserPassword());
        log.info(password);
        log.info(userVo.getPassword());
        //获取解密后的密码
        if (!userVo.getPassword().equals(password)) {
            return new ResultMessage(ResultCode.RESULT_LOGIN.getCode(), ResultCode.RESULT_LOGIN.getStatus(), "用户名或密码错误",null);
        }
        //判断是否是记住密码
        if (userVo.getRemember()) {
            SaTokenUtils.isMarryLogin(user.getUserId());
        }else{
            StpUtil.login(user.getUserId());
        }
        //将当前的用户数据存入session
        SaSession sessionByHeaderToken = SaTokenUtils.getSessionByHeaderToken();
        sessionByHeaderToken.set("userMsg",user);
        return new ResultMessage(ResultCode.RESULT_OK.getCode(), ResultCode.RESULT_OK.getStatus(), null,new LoginVo(SaTokenUtils.getLoginToken().tokenValue,user.getRoleId()));
    }

    /**
     * 修改原密码
     *
     * @param updatePasswordVo
     * @return
     */
    @Override
    public ResultMessage updatePassword(UpdatePasswordVo updatePasswordVo) {
        //获取session值
        SaSession sessionByHeaderToken = SaTokenUtils.getSessionByHeaderToken();
        User user = (User) sessionByHeaderToken.get("userMsg");
        //比对解密后的原密码是否正确
        String password=SaTokenUtils.getAesDecrypt(user.getUserKey(),user.getUserPassword());
        if (!password.equals(updatePasswordVo.getOldPassword())) {
           return new ResultMessage(ResultCode.RESULT_LOGIN.getCode(), ResultCode.RESULT_LOGIN.getStatus(), "原密码验证错误",null);
        }
        //生成新的key，加密新的密码
        String key=UUID.randomUUID().toString().replace("-","");
        String enPassword=SaTokenUtils.getAesEncrypt(key,updatePasswordVo.getNewPassword());
        //写入数据库
        User tempUser = new User();
        tempUser.setUserId(user.getUserId());
        tempUser.setUserKey(key);
        tempUser.setUserPassword(enPassword);
        userMapper.updatePasswordAndKeyByUserId(tempUser);
        //注销登录
        StpUtil.logout();
        return new ResultMessage(ResultCode.RESULT_OK.getCode(), ResultCode.RESULT_OK.getStatus(), null,"修改成功,请重新登录!");
    }

    /**
     * 根据条件查询用户
     *
     * @param userSelectiveVo
     * @return
     */
    @Override
    public ResultMessage selectUsersBySelective(UserSelectiveVo userSelectiveVo) {
        Page<Object> objects = PageHelper.startPage(userSelectiveVo.getPageIndex(), userSelectiveVo.getPageSize());
        Map<String,String> param=new HashMap<>();
        param.put("userId","user_id");
        param.put("userName","user_account");
        if (userSelectiveVo.getSearchType()!=null){
            userSelectiveVo.setSearchType(param.get(userSelectiveVo.getSearchType()));
        }
        List<User> users = userMapper.selectUsersBySelective(userSelectiveVo);
        List<UserResultVo> data=new ArrayList<>();
        users.forEach((item)->{
            Integer count=creditMapper.selectRepayCountByUserIdAndStatus(item.getUserId());
            data.add(new UserResultVo(item.getUserId(),item.getUserAccount(),item.getUserCreatetime(),count));
        });
        return new ResultMessage(ResultCode.RESULT_OK.getCode()
                ,ResultCode.RESULT_OK.getStatus()
                ,null
                ,new PageResult(objects.getTotal(),objects.getPageNum(),objects.getPageSize(),data));
    }

    /**
     * 根据用户ID和用户名删除用户
     *
     * @param userDelVo
     * @return
     */
    @Override
    public ResultMessage deleteUserByIdAndAccount(UserDelVo userDelVo) {
        User user = new User();
        user.setUserId(userDelVo.getUserId());
        user.setUserAccount(userDelVo.getUserAccount());
        boolean flag=userMapper.deleteUserByIdAndAccount(user);
        if (!flag) return  new ResultMessage(ResultCode.RESULT_NULL.getCode(), ResultCode.RESULT_NULL.getStatus(), "非法传参",null);
        return new ResultMessage(ResultCode.RESULT_OK.getCode(), ResultCode.RESULT_OK.getStatus(), null,"删除成功");
    }

    /**
     * 上传文件
     *
     * @param uploadVo
     * @param request
     * @return
     */
    @Override
    public ResultMessage uploadAuthor(UploadVo uploadVo, HttpServletRequest request) throws IOException {
        String author = request.getServletContext().getRealPath("author");
        Integer userId = StpUtil.getLoginIdAsInt();
        File target=new File(author,userId+".jpg");
        if (target.exists()) {
            target.mkdirs();
        }
        uploadVo.getUpload().transferTo(target);
        return new ResultMessage(ResultCode.RESULT_OK.getCode(), ResultCode.RESULT_OK.getStatus(), null , "上传成功");
    }


}
